package net.grandcentrix.thirtyinch.sample.fragmentlifecycle;

import net.grandcentrix.thirtyinch.sample.ResourceTable;
import net.grandcentrix.thirtyinch.TiConfiguration;
import net.grandcentrix.thirtyinch.TiFragment;
import net.grandcentrix.thirtyinch.TiLog;
import net.grandcentrix.thirtyinch.util.BackstackReader;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.app.Context;
import rx.subjects.PublishSubject;

import java.util.UUID;


public abstract class TestFragment extends TiFragment<TestPresenter, TestPresenter.TestView> implements TestPresenter.TestView {
    final static String RETAIN_PRESENTER = "retain";
    static int testFragmentInstanceCount = -1;

    private String TAG = this.getClass().getSimpleName() + "@" + Integer.toHexString(this.hashCode());

    private int instanceNum = Integer.MIN_VALUE;

    private PublishSubject<Boolean> addedState = PublishSubject.create();

    private PublishSubject<Boolean> detachedState = PublishSubject.create();

    private PublishSubject<Boolean> inBackStackState = PublishSubject.create();

    private PublishSubject<Boolean> isActivityChangingConfigState = PublishSubject.create();

    private PublishSubject<Boolean> isActivityFinishingState = PublishSubject.create();

    private PublishSubject<Boolean> removingState = PublishSubject.create();

    private String uuid = null;

    protected abstract int getLayoutResId();

    {
        TiLog.v(TAG, this.toString() + " constructor called");
        testFragmentInstanceCount++;
        instanceNum = testFragmentInstanceCount;
    }

    //TODO 假设认为这个函数由我来调用 @Override
    void onAttach(Context context) {
        addedState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        added -> TiLog.d(TAG, "fragment" + instanceNum + ".setAdded(" + added + ")")
                );
        detachedState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        detached -> TiLog.d(TAG, "fragment" + instanceNum + ".setDetached(" + detached + ")")
                );
        removingState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        removing -> TiLog.d(TAG, "fragment" + instanceNum + ".setRemoving(" + removing + ")")
                );
        inBackStackState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        inBackstack -> TiLog.d(TAG, "fragment" + instanceNum + ".setInBackstack(" + inBackstack + ")")
                );

        isActivityChangingConfigState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        changing ->
                                TiLog.d(TAG,
                                        "hostingActivity" + FragmentLifecycleActivity.fragmentLifecycleActivityInstanceCount + ".setChangingConfiguration(" + changing + ");")
                );
        isActivityFinishingState.startWith(false).distinctUntilChanged().skip(1)
                .subscribe(
                        finishing ->
                                TiLog.d(TAG, "hostingActivity" + FragmentLifecycleActivity.fragmentLifecycleActivityInstanceCount + ".setFinishing(" + finishing + ");")
                );

        printState();
//        super.onAttach(context);
        TiLog.v(TAG, "onAttach(" + context + ")");
        printState();
    }

    @Override
    public void onStart(Intent intent) {
        printState();
        super.onStart(intent);
        TiLog.v(TAG, "onCreate(" + intent + ")");
        printState();
        if (intent != null) {
            uuid = intent.getStringParam("uuid");//TODO: 查看UUID是否是想要的内容
            TiLog.v(TAG, "RESTORED " + uuid);
        }
        if (uuid == null) {
            uuid = UUID.randomUUID().toString();
            TiLog.v(TAG, "CREATED " + uuid);
        }

        if (intent == null) {
            TiLog.d(TAG, "fragment" + instanceNum + ".onCreate(null);");
        } else {
            TiLog.d(TAG, "fragment" + instanceNum + ".onCreate(savedInstanceState);");
        }
        //TODO: 假设在这个地方认为是attach了， 是否ok
        onAttach(getContext());
    }


    @Override
    public Component onComponentAttached(LayoutScatter inflater, ComponentContainer container,
                                         Intent savedInstanceState) {
        super.onComponentAttached(inflater, container, savedInstanceState);
        printState();
        TiLog.v(TAG,
                "onCreateView() called with: inflater = [" + inflater + "], container = [" + container + "], savedInstanceState = [" + savedInstanceState + "]");
        if (savedInstanceState == null) {
            TiLog.d(TAG, "fragment" + instanceNum + ".onCreateView(inflater, null, null);");
        } else {
            TiLog.d(TAG, "fragment" + instanceNum + ".onCreateView(inflater, null, savedInstanceState);");
        }

        Component component = inflater.parse(getLayoutResId(), container, false);
        onViewCreated(component, savedInstanceState);
        return component;
    }

    //TODO  无法模拟， 直接调用
//    @Override
    void onViewCreated(Component view, Intent savedInstanceState) {
        printState();
        TiLog.v(TAG, "onViewCreated");
        printState();

        Text fragmentTag = (Text) view.findComponentById(ResourceTable.Id_sample_text);
        fragmentTag.setText(TAG);
    }

//TODO
//    @Override
//    void onActivityCreated(Intent intent) {
//        super.onActivityCreated(intent);
//        TiLog.v(TAG, "onActivityCreated");
//    }

    //TODO
//    @Override
//    onViewStateRestored(savedInstanceState:Bundle?) {
//        super.onViewStateRestored(savedInstanceState);
//        TiLog.v(TAG, "onViewStateRestored");
//    }

    @Override
    public void onForeground(Intent intent) {
        printState();
        super.onForeground(intent);
        TiLog.d(TAG, "fragment" + instanceNum + ".onStart();");
        printState();
    }

//    @Override
//    onActivityResult(requestCode:Int, resultCode:Int, data:Intent?) {
//        super.onActivityResult(requestCode, resultCode, data)
//        TiLog.v(TAG, "onActivityResult")
//    }

    @Override
    protected void onActive() {
        printState();
        super.onActive();
        TiLog.v(TAG, "onResume");
        printState();
    }

    @Override
    protected void onInactive() {
        printState();
        super.onInactive();
        TiLog.v(TAG, "onPause()");
        printState();
    }

    @Override
    public void onBackground() {
        printState();
        super.onBackground();
        TiLog.d(TAG, "fragment" + instanceNum + ".onStop();");
        printState();
    }

    //TODO
//    @Override
//    onSaveInstanceState(Bundle outState) {
//        super.onSaveInstanceState(outState);
//        printState();
//
//        outState.putString("uuid", uuid);
//
//        TiLog.d(TAG, "fragment" + instanceNum + ".onSaveInstanceState(outState);");
//        printState();
//    }

    //TODO
//    @Override
//    onDestroyView() {
//        printState();
//        super.onDestroyView();
//        TiLog.v(TAG, "onDestroyView")
//        printState();
//
//        TiLog.d(TAG, "fragment" + instanceNum + ".onDestroyView();")
//    }

    @Override
    public void onStop() {
        printState();
        super.onStop();
        TiLog.v(TAG, "onDestroy");
        TiLog.d(TAG, "fragment" + instanceNum + " .onDestroy();");
        printState();
        TiLog.v("FragmentManager", "DESTROYED" + uuid);
        //TODO: 这个模拟是否OK
        onDetach();
    }

    //TODO: 假设这个地方onDetach
//    @Override
    protected void onDetach() {
//        super.onDetach();
        printState();
        TiLog.v(TAG, "onDetach");
        printState();

        addedState.onCompleted();
        detachedState.onCompleted();
        removingState.onCompleted();
        isActivityChangingConfigState.onCompleted();
        isActivityFinishingState.onCompleted();
    }

//    @Override
//    onRequestPermissionsResult(requestCode:Int,
//                               permissions:Array<String>,
//                               grantResults:IntArray) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
//        TiLog.v(TAG, "onRequestPermissionsResult")
//        printState()
//    }

//    @Override
//    onAttachFragment(Fraction childFragment) {
//        super.onAttachFragment(childFragment)
//        printState()
//        TiLog.v(TAG, "onAttachFragment")
//    }

//    @Override
//    onConfigurationChanged(newConfig:Configuration) {
//        super.onConfigurationChanged(newConfig)
//        TiLog.v(TAG, "onConfigurationChanged")
//    }

//    @Override
//    Boolean onContextItemSelected(item:MenuItem) {
//        TiLog.v(TAG, "onContextItemSelected")
//        return super.onContextItemSelected(item)
//    }

//    void onCreateContextMenu(menu:ContextMenu, v:View, menuInfo:ContextMenu.ContextMenuInfo?) {
//        super.onCreateContextMenu(menu, v, menuInfo)
//        TiLog.v(TAG, "onCreateContextMenu")
//    }

//    @Override
//    onCreateOptionsMenu(menu:Menu, inflater:MenuInflater) {
//        super.onCreateOptionsMenu(menu, inflater)
//        TiLog.v(TAG, "onCreateOptionsMenu")
//    }

//    @Override
//    onDestroyOptionsMenu() {
//        super.onDestroyOptionsMenu()
//        TiLog.v(TAG, "onDestroyOptionsMenu")
//    }

//    @Override
//    onHiddenChanged(Boolean hidden) {
//        super.onHiddenChanged(hidden)
//        TiLog.v(TAG, "onHiddenChanged")
//    }

//    @Override
//    onInflate(context:Context, attrs:AttributeSet, savedInstanceState:Bundle?) {
//        super.onInflate(context, attrs, savedInstanceState)
//        TiLog.v(TAG, "onInflate")
//    }

//    @Override
//    onLowMemory() {
//        super.onLowMemory()
//        TiLog.v(TAG, "onLowMemory")
//        printState()
//    }

//    @Override
//    onMultiWindowModeChanged(isInMultiWindowMode:Boolean) {
//        super.onMultiWindowModeChanged(isInMultiWindowMode)
//        TiLog.v(TAG, "onMultiWindowModeChanged")
//        printState()
//    }

//    @Override
//    onOptionsItemSelected(item:MenuItem):Boolean
//    {
//        TiLog.v(TAG, "onOptionsItemSelected")
//        return super.onOptionsItemSelected(item)
//    }

//    @Override
//    onOptionsMenuClosed(menu:Menu) {
//        super.onOptionsMenuClosed(menu)
//        TiLog.v(TAG, "onOptionsMenuClosed")
//    }

//    @Override
//    onPictureInPictureModeChanged(isInPictureInPictureMode:Boolean) {
//        super.onPictureInPictureModeChanged(isInPictureInPictureMode)
//        TiLog.v(TAG, "onPictureInPictureModeChanged")
//        printState()
//    }

//    @Override
//    onPrepareOptionsMenu(menu:Menu) {
//        super.onPrepareOptionsMenu(menu)
//        TiLog.v(TAG, "onPrepareOptionsMenu")
//    }

    @Override
    public TestPresenter providePresenter() {

//        boolean retain = arguments ?.getBoolean(RETAIN_PRESENTER, false) ?:false;
        boolean retain = false;

        TiConfiguration config = new TiConfiguration.Builder()
                .setRetainPresenterEnabled(retain)
                .build();

        TestPresenter presenter = new TestPresenter(config, getClass().getSimpleName());
        TiLog.d(TAG, "created " + presenter);
        TiLog.v(TAG, "retain presenter " + retain + ", " + presenter);

        return presenter;
    }

    // @Override finalize in kotlin
// https://kotlinlang.org/docs/reference/java-interop.html#finalize
//    @Suppress("unused")
    protected void finalize() {
        TiLog.v(TAG, "GCed " + this + ", uuid: " + this.uuid);
    }

    private void printState() {
        //TODO 暂时无法获取这些信息
//        addedState.onNext(isAdded);
//        detachedState.onNext(isDetached);
//        removingState.onNext(isRemoving);
        inBackStackState.onNext(BackstackReader.isInBackStack(this));

        FractionAbility ability = getFractionAbility();
        if (ability == null) {
            return;
        }

        //TODO: 打印isChangingConfigurations
//        isActivityFinishingState.onNext(ability.isFinishing);
//        isActivityChangingConfigState.onNext(activity.isChangingConfigurations);
    }
}
